using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.Json.Nodes;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration
{
    /// <summary>
    /// 配置迁移服务 - 将现有的Upload和CloudStorage配置迁移到集中化Storage配置
    /// </summary>
    public class ConfigurationMigrationService
    {
        private readonly ILogger<ConfigurationMigrationService> _logger;

        public ConfigurationMigrationService(ILogger<ConfigurationMigrationService> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 将现有配置文件迁移到集中化配置
        /// </summary>
        /// <param name="configFilePath">配置文件路径</param>
        /// <param name="backupOriginal">是否备份原文件</param>
        /// <returns>迁移结果</returns>
        public async Task<MigrationResult> MigrateToStorageConfiguration(string configFilePath, bool backupOriginal = true)
        {
            var result = new MigrationResult
            {
                ConfigFile = Path.GetFileName(configFilePath),
                StartTime = DateTime.UtcNow
            };

            try
            {
                _logger.LogInformation("开始迁移配置文件: {ConfigFile}", configFilePath);

                // 检查文件是否存在
                if (!File.Exists(configFilePath))
                {
                    result.Success = false;
                    result.ErrorMessage = $"配置文件不存在: {configFilePath}";
                    return result;
                }

                // 备份原文件
                if (backupOriginal)
                {
                    await BackupOriginalFile(configFilePath, result);
                }

                // 读取并解析配置文件
                var jsonContent = await File.ReadAllTextAsync(configFilePath);
                var jsonObject = JsonSerializer.Deserialize<JsonObject>(jsonContent);

                if (jsonObject == null)
                {
                    result.Success = false;
                    result.ErrorMessage = "无法解析JSON配置文件";
                    return result;
                }

                // 检查是否已经有集中化配置
                if (jsonObject.ContainsKey("Storage"))
                {
                    result.Success = true;
                    result.Message = "配置文件已包含集中化Storage配置，跳过迁移";
                    result.Changes.Add("检测到现有Storage配置，保持不变");
                    return result;
                }

                // 执行迁移
                var migrationChanges = await MigrateConfiguration(jsonObject, result);

                // 保存迁移后的配置
                var options = new JsonSerializerOptions 
                { 
                    WriteIndented = true,
                    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
                };
                
                var updatedJson = JsonSerializer.Serialize(jsonObject, options);
                await File.WriteAllTextAsync(configFilePath, updatedJson);

                result.Success = true;
                result.Message = $"配置迁移完成，应用了 {migrationChanges} 项更改";
                result.EndTime = DateTime.UtcNow;

                _logger.LogInformation("配置迁移完成: {ConfigFile}, 更改数: {Changes}", 
                    configFilePath, migrationChanges);

                return result;
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.ErrorMessage = $"迁移过程中发生异常: {ex.Message}";
                result.EndTime = DateTime.UtcNow;
                
                _logger.LogError(ex, "配置迁移失败: {ConfigFile}", configFilePath);
                return result;
            }
        }

        /// <summary>
        /// 批量迁移多个环境的配置文件
        /// </summary>
        /// <param name="projectRootPath">项目根路径</param>
        /// <returns>批量迁移结果</returns>
        public async Task<BatchMigrationResult> MigrateAllEnvironmentConfigurations(string projectRootPath)
        {
            var result = new BatchMigrationResult
            {
                StartTime = DateTime.UtcNow
            };

            var configFiles = new[]
            {
                "appsettings.json",
                "appsettings.Development.json",
                "appsettings.Production.json"
            };

            foreach (var configFile in configFiles)
            {
                var configPath = Path.Combine(projectRootPath, configFile);
                var migrationResult = await MigrateToStorageConfiguration(configPath, true);
                result.Results.Add(migrationResult);

                if (migrationResult.Success)
                {
                    result.SuccessCount++;
                }
                else
                {
                    result.FailureCount++;
                }
            }

            result.EndTime = DateTime.UtcNow;
            result.TotalDuration = result.EndTime - result.StartTime;

            _logger.LogInformation("批量配置迁移完成。成功: {Success}, 失败: {Failure}", 
                result.SuccessCount, result.FailureCount);

            return result;
        }

        /// <summary>
        /// 生成迁移建议报告
        /// </summary>
        /// <param name="configFilePath">配置文件路径</param>
        /// <returns>迁移建议</returns>
        public async Task<MigrationRecommendation> AnalyzeMigrationRequirements(string configFilePath)
        {
            var recommendation = new MigrationRecommendation
            {
                ConfigFile = Path.GetFileName(configFilePath),
                AnalyzedAt = DateTime.UtcNow
            };

            try
            {
                if (!File.Exists(configFilePath))
                {
                    recommendation.Issues.Add("配置文件不存在");
                    recommendation.RecommendedAction = "创建新的配置文件";
                    return recommendation;
                }

                var jsonContent = await File.ReadAllTextAsync(configFilePath);
                var jsonObject = JsonSerializer.Deserialize<JsonObject>(jsonContent);

                if (jsonObject == null)
                {
                    recommendation.Issues.Add("配置文件格式无效");
                    recommendation.RecommendedAction = "修复JSON格式错误";
                    return recommendation;
                }

                // 检查现有配置结构
                AnalyzeCurrentConfiguration(jsonObject, recommendation);

                // 生成迁移建议
                GenerateMigrationRecommendations(recommendation);

                return recommendation;
            }
            catch (Exception ex)
            {
                recommendation.Issues.Add($"分析失败: {ex.Message}");
                recommendation.RecommendedAction = "检查配置文件格式和权限";
                return recommendation;
            }
        }

        private async Task BackupOriginalFile(string configFilePath, MigrationResult result)
        {
            try
            {
                var backupPath = $"{configFilePath}.backup.{DateTime.Now:yyyyMMdd_HHmmss}";
                var sourceContent = await File.ReadAllTextAsync(configFilePath);
                await File.WriteAllTextAsync(backupPath, sourceContent);
                result.BackupFilePath = backupPath;
                result.Changes.Add($"原配置文件备份到: {Path.GetFileName(backupPath)}");
                
                _logger.LogInformation("配置文件已备份到: {BackupPath}", backupPath);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "无法备份配置文件: {ConfigFile}", configFilePath);
            }
        }

        private async Task<int> MigrateConfiguration(JsonObject jsonObject, MigrationResult result)
        {
            int changeCount = 0;

            // 获取现有的Upload和CloudStorage配置
            var uploadConfig = jsonObject["Upload"]?.AsObject();
            var cloudStorageConfig = jsonObject["CloudStorage"]?.AsObject();

            if (uploadConfig == null && cloudStorageConfig == null)
            {
                result.Changes.Add("未发现Upload或CloudStorage配置，创建默认Storage配置");
                await CreateDefaultStorageConfiguration(jsonObject);
                return 1;
            }

            // 创建集中化Storage配置
            var storageConfig = await CreateCentralizedStorageConfiguration(uploadConfig, cloudStorageConfig, result);
            jsonObject["Storage"] = storageConfig;
            changeCount++;

            result.Changes.Add("创建了集中化Storage配置");

            // 标记旧配置为已弃用（保留兼容性）
            await MarkLegacyConfigurationsAsDeprecated(jsonObject, result);
            changeCount++;

            return changeCount;
        }

        private async Task<JsonObject> CreateCentralizedStorageConfiguration(
            JsonObject? uploadConfig, 
            JsonObject? cloudStorageConfig, 
            MigrationResult result)
        {
            var storageConfig = new JsonObject();

            // 选择主配置源（优先CloudStorage）
            var primaryConfig = cloudStorageConfig ?? uploadConfig;
            var secondaryConfig = cloudStorageConfig != null ? uploadConfig : cloudStorageConfig;

            // 基本配置
            storageConfig["StorageType"] = GetConfigValue(primaryConfig, secondaryConfig, "StorageType", "Local");
            storageConfig["MaxFileSize"] = GetConfigValue(primaryConfig, secondaryConfig, "MaxFileSize", 52428800);
            
            // 数组配置
            storageConfig["AllowedExtensions"] = GetArrayConfig(primaryConfig, secondaryConfig, "AllowedExtensions");
            storageConfig["ImageExtensions"] = GetArrayConfig(primaryConfig, secondaryConfig, "ImageExtensions");

            // 本地存储配置
            await CreateLocalStorageConfiguration(storageConfig, uploadConfig, cloudStorageConfig, result);

            // 缩略图配置
            await CreateThumbnailConfiguration(storageConfig, uploadConfig, cloudStorageConfig);

            // 验证配置
            await CreateValidationConfiguration(storageConfig, uploadConfig, cloudStorageConfig);

            // 高级功能配置
            await CreateAdvancedFeaturesConfiguration(storageConfig);

            // 云存储提供商配置
            await CreateCloudProviderConfigurations(storageConfig, cloudStorageConfig);

            return storageConfig;
        }

        private  Task CreateLocalStorageConfiguration(
            JsonObject storageConfig,
            JsonObject? uploadConfig,
            JsonObject? cloudStorageConfig,
            MigrationResult result)
        {
            var localConfig = new JsonObject();

            var uploadLocal = uploadConfig?[("Local")]?.AsObject();
            var cloudLocal = cloudStorageConfig?[("Local")]?.AsObject();

            // 优先使用CloudStorage的Local配置
            var primaryLocal = cloudLocal ?? uploadLocal;
            var secondaryLocal = cloudLocal != null ? uploadLocal : cloudLocal;

            localConfig["Enabled"] = GetConfigValue(primaryLocal, secondaryLocal, "Enabled", true);
            localConfig["RootPath"] = GetConfigValue(primaryLocal, secondaryLocal, "RootPath", "wwwroot/uploads");
            localConfig["BaseUrl"] = GetConfigValue(primaryLocal, secondaryLocal, "BaseUrl", "/uploads");
            localConfig["TempPath"] = GetConfigValue(primaryLocal, secondaryLocal, "TempPath", "wwwroot/uploads/temp");
            localConfig["ThumbnailPath"] = GetConfigValue(primaryLocal, secondaryLocal, "ThumbnailPath", "wwwroot/uploads/thumbnails");
            localConfig["CreateDateFolders"] = GetConfigValue(primaryLocal, secondaryLocal, "CreateDateFolders", true);
            localConfig["GenerateThumbnails"] = GetConfigValue(primaryLocal, secondaryLocal, "GenerateThumbnails", true);
            localConfig["EnableVirusScan"] = GetConfigValue(primaryLocal, secondaryLocal, "EnableVirusScan", false);
            localConfig["EnableFileDeduplication"] = GetConfigValue(primaryLocal, secondaryLocal, "EnableFileDeduplication", true);

            storageConfig["Local"] = localConfig;
            result.Changes.Add("合并了本地存储配置");
            return  Task.CompletedTask;
        }

        private Task CreateThumbnailConfiguration(JsonObject storageConfig, JsonObject? uploadConfig, JsonObject? cloudStorageConfig)
        {
            var thumbnailConfig = new JsonObject();

            // 从现有配置提取缩略图设置
            var uploadThumbnail = uploadConfig?["ThumbnailSize"]?.AsObject();
            var cloudThumbnail = cloudStorageConfig?["Local"]?["ThumbnailSize"]?.AsObject();

            var primaryThumbnail = cloudThumbnail ?? uploadThumbnail;

            thumbnailConfig["Enabled"] = true;
            thumbnailConfig["Width"] = GetConfigValue(primaryThumbnail, null, "Width", 200);
            thumbnailConfig["Height"] = GetConfigValue(primaryThumbnail, null, "Height", 200);
            thumbnailConfig["Quality"] = GetConfigValue(primaryThumbnail, null, "Quality", "High");

            var supportedFormats = new JsonArray();
            var formats = new[] { "jpg", "jpeg", "png", "gif", "bmp", "webp" };
            foreach (var format in formats)
            {
                supportedFormats.Add(format);
            }
            thumbnailConfig["SupportedFormats"] = supportedFormats;

            storageConfig["Thumbnail"] = thumbnailConfig;
            return Task.CompletedTask;
        }

        private Task CreateValidationConfiguration(JsonObject storageConfig, JsonObject? uploadConfig, JsonObject? cloudStorageConfig)
        {
            var validationConfig = new JsonObject();

            var uploadValidation = uploadConfig?["Validation"]?.AsObject();
            var cloudValidation = cloudStorageConfig?["Validation"]?.AsObject();

            var primaryValidation = cloudValidation ?? uploadValidation;

            validationConfig["StrictMimeTypeCheck"] = GetConfigValue(primaryValidation, null, "StrictMimeTypeCheck", true);
            validationConfig["ScanFileContent"] = GetConfigValue(primaryValidation, null, "ScanFileContent", true);
            validationConfig["BlockExecutableFiles"] = GetConfigValue(primaryValidation, null, "BlockExecutableFiles", true);
            validationConfig["EnableVirusScan"] = GetConfigValue(primaryValidation, null, "EnableVirusScan", false);
            validationConfig["EnableFileDeduplication"] = GetConfigValue(primaryValidation, null, "EnableFileDeduplication", true);

            var blockedExtensions = new JsonArray();
            var blocked = new[] { ".exe", ".bat", ".cmd", ".scr", ".vbs" };
            foreach (var ext in blocked)
            {
                blockedExtensions.Add(ext);
            }
            validationConfig["BlockedExtensions"] = blockedExtensions;

            storageConfig["Validation"] = validationConfig;
            return Task.CompletedTask;
        }

        private Task CreateAdvancedFeaturesConfiguration(JsonObject storageConfig)
        {
            var featuresConfig = new JsonObject
            {
                ["EnableAutoBackup"] = false,
                ["EnableVersionControl"] = false,
                ["EnableAccessLogging"] = true,
                ["EnableStatisticsCollection"] = true,
                ["MaxBackupVersions"] = 5,
                ["AutoCleanupDays"] = 30
            };

            storageConfig["Features"] = featuresConfig;
            return Task.CompletedTask;
        }

        private Task CreateCloudProviderConfigurations(JsonObject storageConfig, JsonObject? cloudStorageConfig)
        {
            if (cloudStorageConfig == null) return Task.CompletedTask;

            // 阿里云OSS
            var aliyunConfig = cloudStorageConfig["AliyunOSS"]?.AsObject();
            if (aliyunConfig != null)
            {
                storageConfig["AliyunOSS"] = JsonNode.Parse(aliyunConfig.ToJsonString());
            }

            // 腾讯云COS
            var tencentConfig = cloudStorageConfig["TencentCOS"]?.AsObject();
            if (tencentConfig != null)
            {
                storageConfig["TencentCOS"] = JsonNode.Parse(tencentConfig.ToJsonString());
            }

            // 华为云OBS
            var huaweiConfig = cloudStorageConfig["HuaweiOBS"]?.AsObject();
            if (huaweiConfig != null)
            {
                storageConfig["HuaweiOBS"] = JsonNode.Parse(huaweiConfig.ToJsonString());
            }
            return Task.CompletedTask;
        }

        private Task CreateDefaultStorageConfiguration(JsonObject jsonObject)
        {
            var defaultConfig = new JsonObject
            {
                ["StorageType"] = "Local",
                ["MaxFileSize"] = 52428800,
                ["AllowedExtensions"] = new JsonArray(".jpg", ".jpeg", ".png", ".gif", ".pdf", ".doc", ".docx", ".txt"),
                ["ImageExtensions"] = new JsonArray(".jpg", ".jpeg", ".png", ".gif"),
                ["Local"] = new JsonObject
                {
                    ["Enabled"] = true,
                    ["RootPath"] = "wwwroot/uploads",
                    ["BaseUrl"] = "/uploads",
                    ["TempPath"] = "wwwroot/uploads/temp",
                    ["ThumbnailPath"] = "wwwroot/uploads/thumbnails",
                    ["CreateDateFolders"] = true,
                    ["GenerateThumbnails"] = true,
                    ["EnableVirusScan"] = false,
                    ["EnableFileDeduplication"] = true
                }
            };

            jsonObject["Storage"] = defaultConfig;
            return Task.CompletedTask;
        }

        private Task MarkLegacyConfigurationsAsDeprecated(JsonObject jsonObject, MigrationResult result)
        {
            // 为旧配置添加弃用标记（仍保留以确保兼容性）
            if (jsonObject.ContainsKey("Upload"))
            {
                var uploadConfig = jsonObject["Upload"]?.AsObject();
                if (uploadConfig != null)
                {
                    uploadConfig["_deprecated"] = "此配置已弃用，请使用Storage配置";
                    result.Changes.Add("Upload配置标记为已弃用（保留兼容性）");
                }
            }

            if (jsonObject.ContainsKey("CloudStorage"))
            {
                var cloudConfig = jsonObject["CloudStorage"]?.AsObject();
                if (cloudConfig != null)
                {
                    cloudConfig["_deprecated"] = "此配置已弃用，请使用Storage配置";
                    result.Changes.Add("CloudStorage配置标记为已弃用（保留兼容性）");
                }
            }
            return Task.CompletedTask;
        }

        private void AnalyzeCurrentConfiguration(JsonObject jsonObject, MigrationRecommendation recommendation)
        {
            recommendation.HasStorageConfig = jsonObject.ContainsKey("Storage");
            recommendation.HasUploadConfig = jsonObject.ContainsKey("Upload");
            recommendation.HasCloudStorageConfig = jsonObject.ContainsKey("CloudStorage");

            if (!recommendation.HasStorageConfig)
            {
                if (recommendation.HasUploadConfig && recommendation.HasCloudStorageConfig)
                {
                    recommendation.ConfigurationStatus = "存在重复配置";
                    recommendation.Issues.Add("Upload和CloudStorage配置重复，建议迁移到集中化Storage配置");
                }
                else if (recommendation.HasUploadConfig || recommendation.HasCloudStorageConfig)
                {
                    recommendation.ConfigurationStatus = "部分配置";
                    recommendation.Issues.Add("存在旧式配置，建议迁移到集中化Storage配置");
                }
                else
                {
                    recommendation.ConfigurationStatus = "缺少存储配置";
                    recommendation.Issues.Add("未发现存储配置，需要创建Storage配置");
                }
            }
            else
            {
                recommendation.ConfigurationStatus = "已使用集中化配置";
                
                if (recommendation.HasUploadConfig || recommendation.HasCloudStorageConfig)
                {
                    recommendation.Issues.Add("存在冗余的旧配置，建议清理Upload/CloudStorage配置");
                }
            }
        }

        private void GenerateMigrationRecommendations(MigrationRecommendation recommendation)
        {
            switch (recommendation.ConfigurationStatus)
            {
                case "存在重复配置":
                    recommendation.RecommendedAction = "执行配置迁移，将Upload和CloudStorage合并为Storage配置";
                    recommendation.Priority = "高";
                    break;
                    
                case "部分配置":
                    recommendation.RecommendedAction = "迁移现有配置到Storage配置并补充缺失功能";
                    recommendation.Priority = "中";
                    break;
                    
                case "缺少存储配置":
                    recommendation.RecommendedAction = "创建新的Storage配置";
                    recommendation.Priority = "高";
                    break;
                    
                case "已使用集中化配置":
                    if (recommendation.HasUploadConfig || recommendation.HasCloudStorageConfig)
                    {
                        recommendation.RecommendedAction = "清理冗余的旧配置以简化配置结构";
                        recommendation.Priority = "低";
                    }
                    else
                    {
                        recommendation.RecommendedAction = "配置已优化，无需迁移";
                        recommendation.Priority = "无";
                    }
                    break;
                    
                default:
                    recommendation.RecommendedAction = "检查配置文件结构";
                    recommendation.Priority = "中";
                    break;
            }
        }

        private JsonNode? GetConfigValue(JsonObject? primary, JsonObject? secondary, string key, JsonNode? defaultValue)
        {
            return primary?[key] ?? secondary?[key] ?? defaultValue;
        }

        private T GetConfigValue<T>(JsonObject? primary, JsonObject? secondary, string key, T defaultValue)
        {
            try
            {
                if (primary != null && primary.TryGetPropertyValue(key, out var primaryValue))
                {
                    if (primaryValue != null)
                        return primaryValue.GetValue<T>();
                }

                if (secondary != null && secondary.TryGetPropertyValue(key, out var secondaryValue))
                {
                    if (secondaryValue != null)
                        return secondaryValue.GetValue<T>();
                }

                return defaultValue;
            }
            catch
            {
                return defaultValue;
            }
        }

        private JsonArray GetArrayConfig(JsonObject? primary, JsonObject? secondary, string key)
        {
            var result = new JsonArray();
            
            var primaryArray = primary?[key]?.AsArray();
            var secondaryArray = secondary?[key]?.AsArray();
            
            var sourceArray = primaryArray ?? secondaryArray;
            
            if (sourceArray != null)
            {
                foreach (var item in sourceArray)
                {
                    result.Add(item?.GetValue<string>());
                }
            }
            
            return result;
        }
    }

    /// <summary>
    /// 迁移结果
    /// </summary>
    public class MigrationResult
    {
        public bool Success { get; set; }
        public string ConfigFile { get; set; } = string.Empty;
        public string Message { get; set; } = string.Empty;
        public string? ErrorMessage { get; set; }
        public List<string> Changes { get; set; } = new List<string>();
        public string? BackupFilePath { get; set; }
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
        public TimeSpan Duration => EndTime - StartTime;
    }

    /// <summary>
    /// 批量迁移结果
    /// </summary>
    public class BatchMigrationResult
    {
        public List<MigrationResult> Results { get; set; } = new List<MigrationResult>();
        public int SuccessCount { get; set; }
        public int FailureCount { get; set; }
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
        public TimeSpan TotalDuration { get; set; }
    }

    /// <summary>
    /// 迁移建议
    /// </summary>
    public class MigrationRecommendation
    {
        public string ConfigFile { get; set; } = string.Empty;
        public DateTime AnalyzedAt { get; set; }
        public string ConfigurationStatus { get; set; } = string.Empty;
        public bool HasStorageConfig { get; set; }
        public bool HasUploadConfig { get; set; }
        public bool HasCloudStorageConfig { get; set; }
        public List<string> Issues { get; set; } = new List<string>();
        public string RecommendedAction { get; set; } = string.Empty;
        public string Priority { get; set; } = "中";
    }
}
